package cn.com.callback

import cn.com.elite.EliteBean
import cn.com.elite.Util
import cn.com.kh.KHDBConfig
import cn.com.kh.KHUtil
import net.sf.json.JSONArray
import net.sf.json.JSONObject
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.jdbc.core.JdbcTemplate

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * @projectName: ngsapitask-hst
 * @package: cn.com
 * @className: chatproxy
 * @author: LiJT
 * @description: 网聊机器人代理接口
 * @date: 2022-11-29 13:21
 * @version: 1.0
 */

public class apiChatRoBotProxy implements ServiceBackInvoke {
    private static final Log log = LogFactory.getLog(apiChatRoBotProxy.class);
    private static String log_Prefix = "RPT Lang Deal-";
    private static String rclient_Lang = "简体";
    private static String[] label_Keys = "sug_title".split(";");
    private static String[] html_Keys = "<strong>=*|</strong>=*|<u>=_|</u>=_|&quot;= |&nbsp;= |&amp;=&|&lt;=<|&gt;=>".split("\\|");

    public String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) {

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");

        // 获取数据源
        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource());

        // 初始化返回结果
        JSONObject result = new JSONObject();

        // 获取调用参数信息
        String paramString = request.getQueryString();
        log.debug("Proxy接收调用参数:" + paramString);

        String question = request.getParameter("question");
        String queue_ID = request.getParameter("queue_ID");
        String client_Lang = request.getParameter("agent_Lang");
        String sessionID = request.getParameter("sessionID");
        String Brand = request.getParameter("Brand");

        // WhatsApp首次问题是触发人工-不能作为问题,如果作为问题则可能存在直接转人工-通过累加实现
        int isFristFlag = 0;
        if (Brand.equals("WhatsApp")) {
            jt.update("Update Chat_Request Set Search_Keyword = Case When Search_Keyword = '' Or Search_Keyword Is Null Then 0 Else Search_Keyword + 1 End Where Chat_Session_Id = ?", sessionID);

            String isFristSQL = '''Select Id From Chat_Request Where Chat_Session_Id = ? And Search_Keyword = '1\'''';
            List<Map<String, Object>> isFristResult = jt.queryForList(isFristSQL, sessionID);
            isFristFlag = isFristResult.size();
        }

        if (isFristFlag > 0) {
            result = JSONObject.fromObject(KHDBConfig.getParamConfig(eliteBean, "iWCRobot_WhatsAppFrist"));
        } else {

            String selectLangSQL = '''Select R1.Id, R1.Name, R1.Description, R1.Workgroup_Id, R1.Locale_Id, R2.Alias, R2.Description
                                      From Queue R1
                                      Left Join Locale R2
                                        On R1.Locale_Id = R2.Id
                                     Where R1.Id = ?''';
            List<Map<String, Object>> selectLangResult = jt.queryForList(selectLangSQL, queue_ID);
            log.debug("Proxy获取本地队列对应语言:" + selectLangResult.toString());

            if (selectLangResult.size() > 0) {
                client_Lang = selectLangResult.get(0).get("Alias").toString();
            }
            rclient_Lang = (client_Lang == "zh_CN") ? "简体" : KHDBConfig.getParam(eliteBean, "SYSENV", "").indexOf("-ML") >= 0 ? "简体" : "繁体";
            log.debug("Proxy接收调用语言:" + client_Lang + " 问题:" + question + " 队列:" + queue_ID + " 机器人答案响应语言client_Lang:" + rclient_Lang);

            try {
                // 判断客户输入的问题是否为预设关键字
                String botDefaultQues = KHDBConfig.getParamConfig(eliteBean, "iWCRobot_DefaultKey");
                botDefaultQues = KHUtil.isNull(botDefaultQues) ? "" : botDefaultQues;

                boolean isDefaultQues = false;
                if (KHUtil.isNull(botDefaultQues)) {
                    // 如果系统参数没有配置则通过KM问题判断是否是预设-默认语言如果是海外环境则默认简体
                    // String rclient_Lang = (client_Lang == "zh_CN") ? "简体" : KHDBConfig.getParam(eliteBean, "SYSENV", "").indexOf("-ML") >= 0 ? "简体" : "繁体";
                    String botDefaultSQL = '''Select R1.Ques_Guid, R2.Rec_Guid, R2.Question, R2.Answer, R2.Answer_Lang, R2.Answer_Type, R2.Html_Answer_Path
                                  From Kh_Robot_Question R1
                                  Left Join Kh_Robot_Question_Lang R2
                                    On R1.Ques_Guid = R2.Ques_Guid
                                 Where Now() Between R1.Starttime And R1.Endtime
                                   And R2.Question = ?
                                   And R2.Answer_Lang = ?
                                   And (R1.Queue_Id = ? Or R1.Queue_Id Is Null Or R1.Queue_Id = '')''';
                    List<Map<String, Object>> botDefaultResult = jt.queryForList(botDefaultSQL, question, rclient_Lang, queue_ID);
                    isDefaultQues = (botDefaultResult.size() > 0);
                    log.debug("Proxy检查客户输入是否通过KM已存在问题:" + botDefaultResult.toString() + " 结果:" + isDefaultQues);
                } else {
                    // 如果系统参数配置则通过参数拆分确认是否是预设
                    String[] botDefaultQuesArr = botDefaultQues.split(",");
                    isDefaultQues = Arrays.asList(botDefaultQuesArr).contains(question);
                    log.debug("Proxy检查客户输入是否系统参数预设关键字:" + botDefaultQues + " 结果:" + isDefaultQues);
                }
                if (isDefaultQues) {

                    // 繁体客户查询本地
                    if (client_Lang != "zh_CN") {
                        result = getLocalBot(eliteBean, jt, question, queue_ID, client_Lang, 1);
                    } else {
                        // 检查机器人是否启用问财(非1只用本地KM维护的问题和答案)
                        String useIWCRobot = KHDBConfig.getParamConfig(eliteBean, "iWCRobot_useIWCRobot");
                        if (KHUtil.isNull(useIWCRobot) || useIWCRobot == "1") {
                            result = getWenCaiBot(eliteBean, jt, paramString, queue_ID);
                        } else {
                            log.debug("Proxy检查机器人是否启用问财(非1只用本地KM维护的问题和答案)：" + useIWCRobot);
                        }

                        if (result.isEmpty()) {
                            result = getLocalBot(eliteBean, jt, question, queue_ID, client_Lang, 1);
                            log.debug("Proxy获取问财机器人未启用或为空(调用获取本地KM结果):" + result.toString());
                        }
                    }
                    if (result.isEmpty()) {
                        result = getLocalBot(eliteBean, jt, question, queue_ID, client_Lang, 0);
                        log.debug("Proxy未获取到机器人答案默认(异常兜底):" + result.toString());
                    }
                } else {
                    // 非系统预设问题直接返回转人工
                    result = JSONObject.fromObject(KHDBConfig.getParamConfig(eliteBean, "iWCRobot_DefaultMan"));
                }

            } catch (Exception e) {
                log.error("Proxy处理接口处理异常", e);

            }

            if (Brand.equals("WhatsApp")) {
                // 机器人答案中特殊富文本替换成CM规则
                try {

                    String answers = result.getJSONArray("answer").getJSONObject(0).getJSONArray("txt").getJSONObject(0).getJSONObject("content").getString("answer");
                    log.debug("机器人答案原始内容：" + answers);

                    answers = doReplaceAll(answers);
                    log.debug("通过配置规则转换后：" + answers);

                    result.getJSONArray("answer").getJSONObject(0).getJSONArray("txt").getJSONObject(0).getJSONObject("content").put("answer", answers);
                } catch (Exception e) {
                    log.warn("机器人答案中特殊富文本替换成CM规则异常:" + e.getMessage());
                }


                // 对内容做长度做处理WhatsApp有些字段长度受限
                try {
                    // 直接转人工的时候Don取的是推荐中的sug_title作为转人工描述,所以转人工无需处理
                    if (result.has("es") && result.getJSONObject("es").has("connect_type")) {
                        log.debug("直接转人工无需处理...");
                    } else {
                        result.getJSONArray("answer").getJSONObject(0).getJSONArray("sugArr").getJSONObject(0).put("sug_title", "Click for more help");
                    }
                } catch (Exception e) {
                    log.warn("对内容做长度做处理WhatsApp有些字段长度受限异常" + e.getMessage());
                }

                // 对内容中富文本做下处理
                result = JSONObject.fromObject(analysisDyn(result.toString()));
                log.debug("Proxy WhatsApp去除Html代码后返回结果:" + result.toString());
            }
        }

        log.debug("Proxy处理完成返回结果:" + result.toString());

        //20230911-新增返回默认 空值判断，避免返回null  chat服务解析聊天历史异常无法展示
        if (result.toString() == null || result.toString().trim().equals("") || result.toString().trim().equals("{}") || result.toString() == "null") {
            log.debug("进来了！:" + result.toString());
            return "";
        }

        return result.toString();
    }

    // 获取本地维护KM
    public static JSONObject getLocalBot(EliteBean eliteBean, JdbcTemplate jt, String question, String queue_ID, String client_Lang, int Ques_Type) {
        JSONObject result = new JSONObject();

        // 正常检索答案时判断是否是直接转人工关键问题
        if (Ques_Type == 1) {
            result = getLocalStaff(eliteBean, jt, question, queue_ID, client_Lang);
        }

        // 判断转人工检查是否有返回-如果有说明要转人工
        if (result.isEmpty()) {
            try {
                // String rclient_Lang = (client_Lang == "zh_CN") ? "简体" : KHDBConfig.getParam(eliteBean, "SYSENV", "").indexOf("-ML") >= 0 ? "简体" : "繁体";
                log.debug("Proxy获取本地[Ques_Type:" + Ques_Type + "]问题语言:" + rclient_Lang + " 问题:" + question + " 队列:" + queue_ID);
                List<Map<String, Object>> selectResult = null;
                String selectSQL = "";
                if (Ques_Type == 1) {
                    selectSQL = '''Select R1.Ques_Guid, R2.Rec_Guid, R2.Question, R2.Answer, R2.Answer_Lang, R2.Answer_Type, R2.Html_Answer_Path
                                  From Kh_Robot_Question R1
                                  Left Join Kh_Robot_Question_Lang R2
                                    On R1.Ques_Guid = R2.Ques_Guid
                                 Where Now() Between R1.Starttime And R1.Endtime
                                   And (R2.Question Like Concat('%', ?, '%') Or R2.Answer Like Concat('%', ?, '%'))
                                   And R2.Answer_Lang = ?
                                   And R1.Ques_Type = ?
                                   And (R1.Queue_Id = ? Or R1.Queue_Id Is Null Or R1.Queue_Id = '')
                                 Order By '',
                                          Case
                                            When R2.Question Like Concat('%', '您好', '%') Then
                                             1
                                            When R2.Answer Like Concat('%', '您好', '%') Then
                                             2
                                            Else
                                             99
                                          End,
                                          R2.Createtime Desc Limit 1''';
                    selectResult = jt.queryForList(selectSQL, question, question, rclient_Lang, Ques_Type, queue_ID);

                } else {
                    selectSQL = '''Select R1.Ques_Guid, R2.Rec_Guid, R2.Question, R2.Answer, R2.Answer_Lang, R2.Answer_Type, R2.Html_Answer_Path
                                  From Kh_Robot_Question R1
                                  Left Join Kh_Robot_Question_Lang R2
                                    On R1.Ques_Guid = R2.Ques_Guid
                                 Where Now() Between R1.Starttime And R1.Endtime
                                   And R2.Answer_Lang = ?
                                   And R1.Ques_Type = ?
                                   And (R1.Queue_Id = ? Or R1.Queue_Id Is Null Or R1.Queue_Id = '')
                                   Order By Robot_ID Desc Limit 1''';

                    selectResult = jt.queryForList(selectSQL, rclient_Lang, Ques_Type, queue_ID);

                }
                log.debug("Proxy获取本地[Ques_Type:" + Ques_Type + "] DB结果:" + selectResult.toString());

                String Ques_Guid = "";
                String Rec_Guid = "";
                String Question = "";
                String Answer = "";
                String Answer_Lang = "";
                String Answer_Type = "";
                if (selectResult.size() > 0) {
                    Ques_Guid = selectResult.get(0).get("Ques_Guid").toString();
                    Rec_Guid = selectResult.get(0).get("Rec_Guid").toString();
                    Question = selectResult.get(0).get("Question").toString();
                    Answer = selectResult.get(0).get("Answer").toString();
                    Answer_Lang = selectResult.get(0).get("Answer_Lang").toString();
                    Answer_Type = selectResult.get(0).get("Answer_Type").toString();

                    // 获取默认问财机器人返回样例
                    result = JSONObject.fromObject(KHDBConfig.getParamConfig(eliteBean, "iWCRobot_DefaultJson-" + client_Lang));

                    // 将样例中的结果修改为问题答案
                    result.getJSONArray("answer").getJSONObject(0).getJSONArray("txt").getJSONObject(0).getJSONObject("content").put("answer", Answer);

                    JSONArray recommendArr = new JSONArray();
                    String recommendSQL = '''Select R1.Ques_Guid, R2.Rec_Guid, R2.Question, R2.Answer, R2.Answer_Lang, R2.Answer_Type, R2.Html_Answer_Path
                                      From Kh_Robot_Question_Recommend R0
                                      Left Join Kh_Robot_Question R1
                                        On R0.Recommend_Ques_Guid = R1.Ques_Guid
                                      Left Join Kh_Robot_Question_Lang R2
                                        On R1.Ques_Guid = R2.Ques_Guid
                                     Where Now() Between R1.Starttime And R1.Endtime
                                       And R2.Answer_Lang = ?
                                       And R0.Ques_Guid = ?
                                     Order By R0.Sort_No''';

                    List<Map<String, Object>> recommendResult = jt.queryForList(recommendSQL, rclient_Lang, Ques_Guid);
                    log.debug("Proxy获取本地[Ques_Type:" + Ques_Type + "]-关联推荐DB结果:" + recommendResult.toString());

                    // 循环解析推荐问题
                    JSONArray sugArray = new JSONArray();
                    for (int i = 0; i < recommendResult.size(); i++) {
                        String re_Answer = recommendResult.get(i).get("Question").toString();
                        recommendArr.add((i + 1) + "-" + re_Answer);

                        JSONObject sugJson = new JSONObject();
                        sugJson.put("click_sug", re_Answer);
                        sugJson.put("display_sug", re_Answer);
                        sugArray.add(sugJson);

                    }

                    if (sugArray.size() > 0) {
                        result.getJSONArray("answer").getJSONObject(0).getJSONArray("sugArr").getJSONObject(0).getJSONArray("sugs").getJSONObject(0).put("sug", sugArray);
                    } else {
                        result.getJSONArray("answer").getJSONObject(0).put("sugArr", sugArray);
                    }

                }
            } catch (Exception e) {
                log.error("Proxy获取本地问题答案异常", e);
            }
        }

        log.debug("Proxy获取本地[Ques_Type:" + Ques_Type + "] JSON返回:" + result.toString());
        return result;

    }

    // 获取本地转人工校验
    public static JSONObject getLocalStaff(EliteBean eliteBean, JdbcTemplate jt, String question, String queue_ID, String client_Lang) {
        JSONObject result = new JSONObject();
        try {
            // String rclient_Lang = (client_Lang == "zh_CN") ? "简体" : KHDBConfig.getParam(eliteBean, "SYSENV", "").indexOf("-ML") >= 0 ? "简体" : "繁体";
            log.debug("Proxy校验问题_是否转人工关键字-语言:" + rclient_Lang + " 问题:" + question + " 队列:" + queue_ID);

            String selectSQL = '''Select R1.Ques_Guid, R2.Rec_Guid, R2.Question, R2.Answer, R2.Answer_Lang, R2.Answer_Type, R2.Html_Answer_Path
                                  From Kh_Robot_Question R1
                                  Left Join Kh_Robot_Question_Lang R2
                                    On R1.Ques_Guid = R2.Ques_Guid
                                 Where Now() Between R1.Starttime And R1.Endtime
                                   And R2.Question Like Concat('%', ?, '%')
                                   And R2.Answer_Lang = ?
                                   And R1.Ques_Type = -1
                                   And (R1.Queue_Id = ? Or R1.Queue_Id Is Null Or R1.Queue_Id = '')
                                   Order By Robot_ID Desc Limit 1''';

            List<Map<String, Object>> selectResult = jt.queryForList(selectSQL, question, rclient_Lang, queue_ID);
            log.debug("Proxy校验问题_是否转人工关键字-结果:" + selectResult.toString());

            if (selectResult.size() > 0) {

                String Ques_Guid = selectResult.get(0).get("Ques_Guid").toString();
                String Question = selectResult.get(0).get("Question").toString();
                String Answer = selectResult.get(0).get("Answer").toString();
                result = JSONObject.fromObject(KHDBConfig.getParamConfig(eliteBean, "iWCRobot_DefaultMan"));
                result.getJSONObject("es").put("expert_type", Question);

            }
        } catch (Exception e) {
            log.error("Proxy校验问题_是否转人工关键字-异常", e);
        }

        return result;

    }

    // 获取问财机器人答案
    public static JSONObject getWenCaiBot(EliteBean eliteBean, JdbcTemplate jt, String paramString, String queue_ID) {
        JSONObject result = new JSONObject();
        try {

            String iWCRobot_URL = KHDBConfig.getAPIURL(eliteBean, "iWCRobot_URL-" + queue_ID);
            log.debug("Proxy获取问财机器人地址:" + iWCRobot_URL);

            String callResult = Util.doHttpGet(iWCRobot_URL + "?" + paramString, "UTF-8", 10000, 0);
            log.debug("Proxy获取问财机器人结果:" + callResult);

            result = JSONObject.fromObject(callResult);
        } catch (Exception e) {
            log.error("Proxy获取问财机器人异常", e);
        }

        return result;

    }

    public static String analysisDyn(String str) {
        org.json.JSONObject json = null;
        org.json.JSONObject re_Json = null;
        try {

            json = new org.json.JSONObject(str);
            re_Json = new org.json.JSONObject(str);
            Set<String> keySet = json.keySet();
            for (String key : keySet) {
                Object obj = json.get(key);
                if (obj instanceof org.json.JSONArray) {
                    org.json.JSONArray arr = (org.json.JSONArray) obj;
                    for (int i = 0; i < arr.length(); i++) {
                        if (arr.get(i) instanceof org.json.JSONObject) {
                            String child = analysisDyn(arr.get(i).toString());
                            arr.put(i, new org.json.JSONObject(child));
                        } else {
                            arr.put(i, arr.get(i).toString());
                        }
                    }
                    re_Json.put(key, arr);
                } else if (obj instanceof org.json.JSONObject) {
                    org.json.JSONObject sub = (org.json.JSONObject) obj;
                    String substr = analysisDyn(sub.toString());
                    re_Json.put(key, new org.json.JSONObject(substr));
                } else {
                    String key_Value = obj.toString().trim();
                    if (Arrays.asList(label_Keys).contains(key)) {

                        log.debug(log_Prefix + "#原始信息-key：" + key + " value：" + key_Value);

                        // 判断是否已经替换
                        if (!KHUtil.isNull(key_Value)) {

                            // 1-处理标签中有i class
                            try {
                                key_Value = key_Value.replaceAll("<br/>", "");
                                log.debug(log_Prefix + "#语言数据-key：" + key + " value：" + key_Value);
                                re_Json.put(key, key_Value);

                            } catch (Exception e) {
                                log.debug(log_Prefix + "#语言数据-key：" + key + " value：" + key_Value + " 异常-" + e.getMessage());

                            }
                        } else {
                            // 语言字段为空或未包含中文
                            log.debug(log_Prefix + "#语言数据-key：" + key + " value：" + key_Value + " 语言字段为空或未包含中文");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.warn("analysisDyn处理富文本异常", e);

        }
        return re_Json.toString();
    }

    // 替换Main
    public static String doReplaceAll(String parent) {
        try {
            for (int i = 0; i < html_Keys.length; i++) {
                String[] html_Key = html_Keys[i].split("=");
                parent = replaceAll(parent, html_Key[0], html_Key[1]);
            }
        } catch (Exception e) {
            log.warn("机器人答案中特殊富文本替换成CM规则异常", e);

        }

        return parent;

    }

    // 替换全部
    public static String replaceAll(String parent, String targetEle, String replaceEle) {
        if (!parent.contains(targetEle)) {
            return parent;
        } else {
            int beginIndex = parent.indexOf(targetEle);
            int endIndex = beginIndex + targetEle.length();
            return parent.substring(0, beginIndex) + replaceEle + replaceAll(parent.substring(endIndex), targetEle, replaceEle);
        }

    }

}
